home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * TrivSTrv.c - Construct a trivariate using a set of surfaces. *
- *******************************************************************************
- * Written by Gershon Elber, Sep. 91. *
- ******************************************************************************/
-
- #include "triv_loc.h"
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Constructs a trivariate using a set of surfaces. Surfaces are made to be M
- * compatible and then each is substituted into the new trivariate's mesh as M
- * a row. M
- * If the OtherOrder is less than the number of curves, number of curves is M
- * used. M
- * A knot vector is formed with uniform open end for the other direction, M
- * so it interpolates the first and last surfaces. M
- * Note, however, that only the first and the last surfaces are M
- * interpolated if OtherOrder is greater than 2. M
- * *
- * PARAMETERS: M
- * SrfList: List of surfaces to consturct a trivariate with. M
- * OtherOrder: Other, third, order of trivariate. M
- * *
- * RETURN VALUE: M
- * TrivTVStruct *: Constructed trivariate from surfaces. M
- * *
- * KEYWORDS: M
- * TrivTVFromSrfs, trivar constructors M
- *****************************************************************************/
- TrivTVStruct *TrivTVFromSrfs(CagdSrfStruct *SrfList, int OtherOrder)
- {
- CagdBType IsNotRational;
- int i, j, NumSrfs, UOrder, VOrder, WOrder, MaxCoord, Length;
- CagdRType **TVPoints;
- CagdSrfStruct *Srf, **SrfVec;
- TrivTVStruct *TV;
-
- /* Find out how many curves we have and put them in a linear vector. */
- /* Note the vector have a COPY of the curves so we can modify them. */
- for (NumSrfs = 0, Srf = SrfList;
- Srf != NULL;
- NumSrfs++, Srf = Srf -> Pnext);
- SrfVec = (CagdSrfStruct **) IritMalloc(sizeof(CagdSrfStruct *) * NumSrfs);
- for (i = 0, Srf = SrfList;
- i < NumSrfs;
- i++, Srf = Srf -> Pnext)
- SrfVec[i] = CagdSrfCopy(Srf);
-
- /* Traverse vector in a O(n^2) fashion and make all curves compatible. */
- for (i = 0; i < NumSrfs - 1; i++)
- for (j = i + 1; j < NumSrfs; j++)
- CagdMakeSrfsCompatible(&SrfVec[i], &SrfVec[j],
- TRUE, TRUE, TRUE, TRUE);
-
- /* Construct the surface. All required information is now available. */
- UOrder = SrfVec[0] -> UOrder;
- VOrder = SrfVec[0] -> VOrder;
- WOrder = MIN(NumSrfs, OtherOrder);
- if (NumSrfs == WOrder && SrfVec[0] -> GType == CAGD_CBEZIER_TYPE) {
- /* Allocate a bezier surface. */
- TV = TrivBzrTVNew(SrfVec[0] -> ULength, SrfVec[0] -> VLength,
- NumSrfs, SrfVec[0] -> PType);
- }
- else {
- /* Allocate a bspline surface. */
- TV = TrivBspTVNew(SrfVec[0] -> ULength, SrfVec[0] -> VLength,
- NumSrfs, UOrder, VOrder, WOrder,
- SrfVec[0] -> PType);
- IritFree((VoidPtr) TV -> UKnotVector);
- TV -> UKnotVector = BspKnotCopy(SrfVec[0] -> UKnotVector,
- CAGD_SRF_UPT_LST_LEN(SrfVec[0]) +
- UOrder);
- IritFree((VoidPtr) TV -> VKnotVector);
- TV -> VKnotVector = BspKnotCopy(SrfVec[0] -> VKnotVector,
- CAGD_SRF_VPT_LST_LEN(SrfVec[0]) +
- VOrder);
- BspKnotUniformOpen(NumSrfs, WOrder, TV -> WKnotVector);
- }
-
- /* Substitute each curve as a row into the surface mesh and delete it. */
- TVPoints = TV -> Points;
- i = 0;
- MaxCoord = CAGD_NUM_OF_PT_COORD(SrfVec[0] -> PType),
- IsNotRational = !CAGD_IS_RATIONAL_SRF(SrfVec[0]);
- Length = SrfVec[0] -> ULength * SrfVec[0] -> VLength;
-
- for (j = 0; j < NumSrfs; j++) {
- int k;
- CagdRType
- **SrfPoints = SrfVec[j] -> Points;
-
- for (k = IsNotRational; k <= MaxCoord; k++)
- CAGD_GEN_COPY(&TVPoints[k][i], SrfPoints[k],
- sizeof(CagdRType) * Length);
-
- CagdSrfFree(SrfVec[j]);
- i += Length;
- }
-
- IritFree((VoidPtr) SrfVec);
-
- return TV;
- }
-